﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kaidou.Persister;
using Kaidou.Util;
using Kaidou.Model;
using System.Collections;
using System.Resources;

namespace Kaidou.Bll
{
    /**zhou-anyuan
     * 報告率集約のManager
     *
     * @version 1.0
     */
    public class TRN_RepoconcentManager
    {
        private ResourceManager m_ResourceManager = null;

        private TRN_RepoconcentManager()
        {

        }

        /**
         * コンストラクタ
         * @param ctx Context
         */
        public TRN_RepoconcentManager(ResourceManager resourceManager)
        {
            this.m_ResourceManager = resourceManager;
        }

        //private const String PROCESSFAXOCRDATA_FUNCTION_NAME = "Concentration_exec";

        /**
         * 報告率計算クラスのメインメソッド
         *
         */
        public bool Concentration_exec()
        {
            SqlDB con = new SqlDB();
            bool chkbln = false;
            //組合員リスト保持よう
            List<TrnReportRate> UnionList = new List<TrnReportRate>();
            //今年用
            List<TrnReportRate> nowList = new List<TrnReportRate>();
            //昨年用
            List<TrnReportRate> lastList = new List<TrnReportRate>();

            List<TrnReportRate> lastList2 = new List<TrnReportRate>();
            List<TrnReportRate> lastList3 = new List<TrnReportRate>();
            List<TrnReportRate> lastList4 = new List<TrnReportRate>();
            //削除レコード数
            int delcnt = 0;

            try
            {
                //コネクション取得
                //con = new SqlDB();
                con.TransBegin();
                //パーシスターを作成
                TRN_Report_Rate_Persister perRR = new TRN_Report_Rate_Persister();
                MST_UnionPersister perMU = new MST_UnionPersister();

                //組合員リストを取得する。
                LogManager.debug("TRN_RepoconcentManager - 組合員リスト取得開始");
                UnionList = perMU.getUnion_codeList(con);
                LogManager.debug("TRN_RepoconcentManager - 組合員リスト取得終了");

                //現在の西暦を桁を取得する。
                System.DateTime date = System.DateTime.Now;
                int date_yyyy = date.Year;
                //集約日時を取得する。
                System.DateTime Concentration_time = perRR.getCurrentTimestamp(con);

                //trn_report_rateテーブルのレコード削除
                delcnt = perRR.delete(con);
                LogManager.debug("TRN_RepoconcentManager - 報告率明細テーブルのレコードを削除しました。削除レコード数:" + delcnt);

                LogManager.debug("TRN_RepoconcentManager - 報告率集計開始");
                //本年中の報告率の取得
                nowList = getSealTotal(con, date_yyyy, UnionList, Concentration_time);
                //本年度の報告率のインサート
                for (int i = 0; i < nowList.Count; i++)
                {
                    TrnReportRate model_01 = nowList[i];
                    perRR.insert(con, model_01);
                }
                //昨年中の報告率の取得
                lastList = getSealTotal(con, date_yyyy - 1, UnionList, Concentration_time);
                //昨年度の報告率のインサート
                for (int j = 0; j < lastList.Count; j++)
                {
                    TrnReportRate model_02 = lastList[j];
                    perRR.insert(con, model_02);
                }

                //昨年中の報告率の取得
                lastList2 = getSealTotal(con, date_yyyy - 2, UnionList, Concentration_time);
                //昨年度の報告率のインサート
                for (int j = 0; j < lastList2.Count; j++)
                {
                    TrnReportRate model_03 = lastList2[j];
                    perRR.insert(con, model_03);
                }

                //昨年中の報告率の取得
                lastList3 = getSealTotal(con, date_yyyy - 3, UnionList, Concentration_time);
                //昨年度の報告率のインサート
                for (int j = 0; j < lastList3.Count; j++)
                {
                    TrnReportRate model_04 = lastList3[j];
                    perRR.insert(con, model_04);
                }

                //昨年中の報告率の取得
                lastList4 = getSealTotal(con, date_yyyy - 4, UnionList, Concentration_time);
                //昨年度の報告率のインサート
                for (int j = 0; j < lastList4.Count; j++)
                {
                    TrnReportRate model_05 = lastList4[j];
                    perRR.insert(con, model_05);
                }
                con.TransCommit();
                LogManager.debug("TRN_RepoconcentManager - 報告率集計終了");

            }
            catch (Exception pe)
            {
                try
                {
                    con.TransRollback();
                }
                catch (Exception e)
                {

                }
                LogManager.error("TRN_RepoconcentManager - Concentration_exec" + pe.ToString());
                throw pe;
            }

            finally
            {
                try
                {
                    //コネクションを開放
                    con.Close();
                }
                catch (Exception e)
                {
                    LogManager.fatal("TRN_RepoconcentManager - Concentration_exec - finally" + e.ToString());
                }
            }
            return chkbln;
        }

        /**
         * 購入枚数を報告枚数を取得する
         * @param nen 集計年数
         * @return 報告率明細モデルを格納したVector
         */
        public static List<TrnReportRate> getSealTotal(SqlDB con, int nen, List<TrnReportRate> unionlist, System.DateTime Concentration_time)
        {

            Hashtable hash01 = new Hashtable();
            Hashtable hash02 = new Hashtable();
            List<TrnReportRate> List = new List<TrnReportRate>();
            String date_yyyy = nen.ToString();

            try
            {
                //パーシスターを作成
                TRN_Purch_SealPersister perPS = new TRN_Purch_SealPersister();
                TRN_Report_Rate_Persister perRR = new TRN_Report_Rate_Persister();
                //集計年度の購入枚数の取得
                hash01 = perPS.getJuchuSealTotal(con, date_yyyy);
                //集計年度の報告枚数の取得
                hash02 = perRR.getReportSealTotal(con, date_yyyy);
                //集計年度の報告率の計算
                List = calReport_rate(hash01, hash02, unionlist, date_yyyy, Concentration_time);
            }
            catch (Exception pe)
            {
                LogManager.error("TRN_FaxocrManager - getSealTotal" + pe.ToString());
                throw pe;
            }
            //finally {
            //    try {
            //        //コネクションを開放
            //        Pool.releaseConnection(con);
            //    } catch (Exception e) {
            //        Logger.logWrite(TRN_FaxocrManager.class.getName(), "F", "getSealTotal - finally", e);
            //    }
            //}
            return List;
        }

        private static List<TrnReportRate> calReport_rate(Hashtable order_list, Hashtable report_list, List<TrnReportRate> unionlist, String date_yyyy, DateTime Concentration_time)
        {
            //返値用Vector
            List<TrnReportRate> rtnvct = new List<TrnReportRate>();
            //報告率の少数点以下の桁数を設定（00.00の形）
            //NumberFormat formatter = NumberFormat.getNumberInstance();
            //formatter.setMaximumFractionDigits(2);

            //報告率を計算しモデルを返値用のvectorへ格納
            for (int i = 0; i < unionlist.Count; i++)
            {
                TrnReportRate model = unionlist[i];
                //購入枚数の設定
                if ((String)order_list[model.Id.UnionCode] == null)
                {
                    //対象データが無いので0を入力
                    model.OrderSealQty = 0;
                }
                else
                {
                    //対象データがあるのでそれを設定
                    model.OrderSealQty = int.Parse((string)order_list[model.Id.UnionCode]);
                }
                //報告枚数の設定
                if ((String)report_list[model.Id.UnionCode] == null)
                {
                    //対象データが無いので0を入力
                    model.ReportSealQty = 0;
                }
                else
                {
                    //対象データがあるのでそれを設定
                    model.ReportSealQty = int.Parse((string)report_list[model.Id.UnionCode]);
                }

                //報告率の設定　 (報告枚数/購入枚数) * 100
                if (model.OrderSealQty == 0)
                {
                    model.ReportRate = 0.00f;
                }
                else
                {
                    float rate = ((float)model.ReportSealQty / (float)model.OrderSealQty) * 100;
                    model.ReportRate = (float)Math.Round(rate, 2);
                }
                //集約対象の年数をセット
                model.Id.SealYear = short.Parse(date_yyyy);
                //集計時刻のセット
                model.CountDate = Concentration_time;
                rtnvct.Add(model);
            }
            return rtnvct;
        }

        /**
         * 報告率の取得
         * @param	union_code	組合員コード
         * @return	報告率明細のモデルの入ったVector
         */
        public ArrayList getReportRates(String union_code)
        {
            SqlDB con = null;
            ArrayList vct = new ArrayList();
            TrnReportRate model_total = new TrnReportRate();
            int order_seal_qty = 0;
            int report_seal_qty = 0;

            float report_rate = 0.00f;
            try
            {
                //			con = Pool.getConnection();
                con = new SqlDB();

                TRN_Report_Rate_Persister parRP = new TRN_Report_Rate_Persister();
                vct = parRP.getReportRates(union_code);

                for (int i = 0; i < vct.Count; i++)
                {
                    TrnReportRate model = (TrnReportRate)vct[i];

                    //購入枚数を合計する
                    order_seal_qty = order_seal_qty + model.OrderSealQty;
                    //報告枚数を合計する
                    report_seal_qty = report_seal_qty + model.ReportSealQty;
                }
                //合計枚数を累計用モデルへ入れる
                model_total.OrderSealQty = order_seal_qty;
                model_total.ReportSealQty = report_seal_qty;
                //累計の報告率を計算
                if (report_seal_qty != 0)
                {
                    report_rate = ((float)report_seal_qty / (float)order_seal_qty) * 100;
                }
                model_total.ReportRate = (float)Math.Round(report_rate, 2);
                //累計用モデルをVectorの最初に追加
                vct.Insert(0, model_total);

            }
            catch (Exception pe)
            {
                LogManager.error("TRN_RepoconcentManager - getReportRates" + pe.ToString());
                throw pe;
            }
            finally
            {
                try
                {
                    //				Pool.releaseConnection(con);
                    con.Close();
                }
                catch (Exception e)
                {
                    LogManager.error("TRN_RepoconcentManager - getReportRates - finally" + e.ToString());
                }
            }
            return vct;
        }

        /**
         * 発注処理が出来るかどうかのチェック
         * @param	union_code	組合員コード
         * @return	報告率明細のモデルの入ったVector
         */
        public bool chkReportRate(String union_code)
        {
            SqlDB con = null;
            ArrayList vct = new ArrayList();
            int order_seal_qty = 0;
            int report_seal_qty = 0;

            bool rtnbln = false;
            float report_rate = 0.00f;
            String flg = "";
            try
            {
                //			con = Pool.getConnection();
                con = new SqlDB();

                TRN_Report_Rate_Persister parRP = new TRN_Report_Rate_Persister();
                MST_UnionPersister parUnion = new MST_UnionPersister();
                vct = parRP.getReportRates(union_code);

                for (int i = 0; i < vct.Count; i++)
                {
                    TrnReportRate model = (TrnReportRate)vct[i];

                    //購入枚数を合計する
                    order_seal_qty = order_seal_qty + model.OrderSealQty;
                    //報告枚数を合計する
                    report_seal_qty = report_seal_qty + model.ReportSealQty;
                }

                //累計の報告率を計算
                if (report_seal_qty != 0)
                {
                    report_rate = ((float)report_seal_qty / (float)order_seal_qty) * 100;
                }
                //規定報告率の読み込み
                String default_rate = m_ResourceManager.GetString("kaidou_reportreta");
                flg = parUnion.getCancelflg(con, union_code);

                if (report_rate >= float.Parse(default_rate) || flg == "1")
                {
                    rtnbln = true;
                }
                else
                {
                    rtnbln = false;
                }
            }
            catch (Exception pe)
            {
                LogManager.error("TRN_RepoconcentManager - chkReportRate" + pe.ToString());
                //throw pe;

            }
            finally
            {
                try
                {
                    //				Pool.releaseConnection(con);
                    con.Close();
                }
                catch (Exception e)
                {
                    LogManager.error("TRN_RepoconcentManager - chkReportRate - finally" + e.ToString());
                }
            }
            return rtnbln;
        }

        /**
         * 規定報告率の取得
         * @param	union_code	組合員コード
         * @return	報告率明細のモデルの入ったVector
         */
        public String getDefaultRate()
        {
            //規定報告率の読み込み
            return m_ResourceManager.GetString("kaidou.reportreta");
        }

    }
}
